package test.serverframe.armc.server.manager.service.exec;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import test.serverframe.armc.server.manager.domain.IntegrationTestInterfaceRecord;
import test.serverframe.armc.server.manager.domain.IntegrationTestInterfaceUseCaseAsso;
import test.serverframe.armc.server.manager.domain.IntegrationTestRecord;
import test.serverframe.armc.server.manager.domain.TestUseCase;
import test.serverframe.armc.server.manager.service.exec.caller.TestUseCaseHTTPCaller;
import test.serverframe.armc.server.manager.service.exec.params.InterfaceTestParams;
import test.serverframe.armc.server.manager.service.exec.params.TestUseCaseTestParams;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author LeiZhenYang
 * @date 2018.12.07
 */
public class InterfaceTester implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(InterfaceTester.class);

    private InterfaceTestParams params;

    /**
     * 初始化集成测试接口执行器
     */
    public InterfaceTester(InterfaceTestParams params) {
        this.params = params;
    }

    @Override
    public void run() {
        List<IntegrationTestInterfaceUseCaseAsso> assos = params.getTestInterface().getAssos();
        IntegrationTestInterfaceRecord interfaceRecord = new IntegrationTestInterfaceRecord();
        try {
            String itirId = UUID.randomUUID().toString();
            interfaceRecord.setId(itirId);
            interfaceRecord.setItrId(params.getItrId());
            // 当前接口的测试用例总并发数
            int interfaceTotalCount = assos.size() * params.getConcurrentCount();
            interfaceRecord.setTotal(interfaceTotalCount);
            interfaceRecord.setSuccessTotal(0);
            interfaceRecord.setStartTime(new Date());
            interfaceRecord.setInterfaceId(params.getTestInterface().getInterfaceId());
            interfaceRecord.setInterfaceName(params.getTestInterface().getInterfaceName());
            if (assos != null) {

                for (IntegrationTestInterfaceUseCaseAsso asso : assos) {
                    // 获取当前接口的测试用例
                    TestUseCase testUseCase = asso.getTestUseCase();
                    String ucId = testUseCase.getId();
                    // 测试用例请求成功数
                    AtomicInteger testUseCaseSuccessCounter = new AtomicInteger(0);
                    // 测试用例响应总数
                    AtomicInteger testUseCaseCallbackCounter = new AtomicInteger(0);
                    // 测试用例参数
                    TestUseCaseTestParams params = new TestUseCaseTestParams(this.params);
                    params.setConcurrentTestUseCaseCallbackTotalCounter(testUseCaseCallbackCounter);
                    params.setConcurrentTestUseCaseSuccessTotalCounter(testUseCaseSuccessCounter);
                    params.setItirId(itirId);
                    params.setUcId(ucId);
                    params.setInterfaceTestTotalCount(interfaceTotalCount);
                    // 注入所需的服务
                    params.setIntegrationTestInterfaceUseCaseRecordAssoService(this.params.getIntegrationTestInterfaceUseCaseRecordAssoService());
                    params.setIntegrationTestRecordService(this.params.getIntegrationTestRecordService());
                    params.setInterfaceTestService(this.params.getInterfaceTestService());
                    params.setInterfaceRecordService(this.params.getInterfaceRecordService());
                    params.setAssertService(this.params.getAssertService());
                    // 异步调用接口
                    TestUseCaseHTTPCaller.newAsyncInstance(testUseCase, params).asyncCall();
                }
                interfaceRecord.setStatus(IntegrationTestRecord.Status.Working);
            }
        } catch (Exception e) {
            e.printStackTrace();
            interfaceRecord.setStatus(IntegrationTestRecord.Status.Failure);
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        } finally {
            params.getInterfaceRecordService().insertSelective(interfaceRecord);
        }
    }
}
